/*
 * Copyright (c) 2009
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.dcarew.hudson;

import org.dcarew.hudson.utils.HudsonUtils;
import org.dcarew.hudson.utils.NotificationUtils;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

/**
 * 
 * 
 * @author Devon Carew
 */
public class HudsonPreferencePage
	extends PreferencePage
	implements IWorkbenchPreferencePage
{
	public static final String PAGE_ID = "org.dcarew.hudson.prefPage";
	
	private Text 		urlText;
	private Button 		selfSignedButton;
	
	private Text 		usernameText;
	private Text 		passwordText;
	
	private Button		notificationButton;
	
	
	/**
	 * 
	 */
	public HudsonPreferencePage()
	{
		super("Hudson");
		
		setDescription("Hudson plugin version " + HudsonPlugin.getVersion() + ".");
		
		noDefaultAndApplyButton();
	}
	
	public void init(IWorkbench workbench)
	{
		
	}
	
	protected Control createContents(Composite parent)
	{
		// Server url group
		Group group = new Group(parent, SWT.NONE);
		group.setText("Hudson Server");
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		group.setLayout(new GridLayout(2, false));
		
		Label label = new Label(group, SWT.NONE);
		label.setText("Server URL:");
		
		urlText = new Text(group, SWT.SINGLE | SWT.BORDER);
		urlText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		urlText.addModifyListener(new ModifyListener() {	
			public void modifyText(ModifyEvent event) {
				verifyURLText();
			}
		});
		
		label = new Label(group, SWT.NONE);
		
		selfSignedButton = new Button(group, SWT.CHECK);
		selfSignedButton.setText("Allow self-signed certificates");
		
		// authentication group
		group = new Group(parent, SWT.NONE);
		group.setText("Authentication Information");
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		group.setLayout(new GridLayout(2, false));
		
		label = new Label(group, SWT.NONE);
		label.setText("User Name:");
		
		usernameText = new Text(group, SWT.SINGLE | SWT.BORDER);
		usernameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		label = new Label(group, SWT.NONE);
		label.setText("Password:");
		
		passwordText = new Text(group, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
		passwordText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		// Notification group
		if (NotificationUtils.isMylynAvailable())
		{
			group = new Group(parent, SWT.NONE);
			group.setText("Notifications");
			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			group.setLayout(new GridLayout());
			
			notificationButton = new Button(group, SWT.CHECK);
			notificationButton.setText("Show notifications for build failures");
		}
		
		// Test connection button
		Button testConnection = new Button(parent, SWT.PUSH);
		testConnection.setText("Test Connection...");
		testConnection.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END
			| GridData.VERTICAL_ALIGN_END | GridData.GRAB_VERTICAL));
		testConnection.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				testConnection();
			}			
		});
		
		initFromPreferences();
		
		return parent;
	}
	
	private void initFromPreferences()
	{
		urlText.setText(HudsonPlugin.getBaseURL());
		selfSignedButton.setSelection(HudsonPlugin.getAllowSelfSigned());
		
		HudsonCredentials credentials = HudsonPlugin.getUserCredentials();
		
		if (credentials != null)
		{
			usernameText.setText(credentials.getUserName());
			passwordText.setText(credentials.getPassword());
		}
		
		if (notificationButton != null)
		{
			notificationButton.setSelection(!HudsonPlugin.getDontNotify());
		}
	}
	
	public boolean performOk()
	{
		HudsonPlugin.setBaseURL(urlText.getText());
		HudsonPlugin.setAllowSelfSigned(selfSignedButton.getSelection());
		HudsonPlugin.setUserCredentials(usernameText.getText(), passwordText.getText());
		
		HudsonUpdateJob.refresh();
		
		if (notificationButton != null)
		{
			HudsonPlugin.setDontNotify(!notificationButton.getSelection());
		}
		
		return super.performOk();
	}
	
	protected void verifyURLText()
	{
		String text = urlText.getText();
		
		if (text.length() > 0 && !text.endsWith("/"))
		{
			setMessage("URL must end with /", IMessageProvider.WARNING);
		}
		else
		{
			clearMessage();
		}
	}
	
	protected void testConnection()
	{
		final HudsonCommunications comm = new HudsonCommunications();
		
		comm.setBaseURL(urlText.getText());
		comm.setAllowSelfSigned(selfSignedButton.getSelection());
		comm.setUsername(usernameText.getText());
		comm.setPassword(passwordText.getText());
		
		BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
			public void run()
			{
				if (comm.updateStatus())
				{
					setMessage("Connection successful.", IMessageProvider.INFORMATION);
					
					clearMessageDelayed(2000);
				}
				else
				{
					setMessage(comm.getSummary(), IMessageProvider.WARNING);
				}
			}
		});
	}
	
	private void clearMessage()
	{
		if (urlText != null && !urlText.isDisposed())
		{
			setMessage(null);
		}
	}
	
	private void clearMessageDelayed(final int millis)
	{
		final String 	oldMessage = getMessage();
		final Display 	display = getShell().getDisplay();
		
		new Thread(new Runnable() {
			public void run()
			{
				HudsonUtils.sleepMillis(millis);
				
				display.asyncExec(new Runnable() {
					public void run()
					{
						if (HudsonUtils.safeEquals(oldMessage, getMessage()))
						{
							clearMessage();
						}
					}
				});
			}
		}).start();
	}
	
}
